package cn.sykj.car.service.impl;

import cn.sykj.car.common.StatusCode;
import cn.sykj.car.dict.*;
import cn.sykj.car.entity.*;
import cn.sykj.car.exception.CommonException;
import cn.sykj.car.mapper.CarRechargeMapper;
import cn.sykj.car.service.*;
import cn.sykj.car.utils.BusinessUtils;
import cn.sykj.car.utils.Utils;
import cn.sykj.car.vo.CarRechargeVO;
import cn.sykj.car.vo.ResponseMessageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * <p>
 * 充值记录 服务实现类
 * </p>
 *
 * @author yuhao
 * @since 2021-06-30
 */
@Service
public class CarRechargeServiceImpl extends ServiceImpl<CarRechargeMapper, CarRecharge> implements ICarRechargeService {

    @Resource
    ICarUsersService carUsersService;

    @Resource
    IConfigRechargeService configRechargeService;

    @Resource
    ICarUserWalletLogService carUserWalletLogService;

    @Resource
    ICarUserWalletService carUserWalletService;

    /**
     * 人工在管理端充值（模拟充值过程，不实际调接口充值）
     * 1-纯充值  2-添加会员时顺便充值  3-修改会员时充值  4-修改会员时修改余额
     *
     * @param carRecharge
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public ResponseMessageVO addRecharge(CarRechargeVO carRecharge) throws Exception {

        if (Utils.isEmpty(carRecharge)
                || Utils.isEmpty(carRecharge.getRechargeFlag())
                || Utils.isEmpty(carRecharge.getPayWay())) {
            throw new CommonException("", "参数不能为空；且充值标记、支付方式必填！");
        }

        if (Utils.isEmpty(carRecharge.getCardCategory())) {
            throw new CommonException("", "充值的卡片类型不能为空！即必填月卡、季卡、普通储值卡等类型！");
        }

        CarUsers carUsers;
        boolean ret = true;
        ResponseMessageVO responseMessageVO = new ResponseMessageVO();

        // 验证用户id
        if (Utils.isEmpty(carRecharge.getUserId())) {
            throw new CommonException(StatusCode.USER_NOT_FOUND.getCode(),
                    StatusCode.USER_NOT_FOUND.getMsg());
        }
        carUsers = carUsersService.getById(carRecharge.getUserId());
        if (Utils.isEmpty(carUsers)) {
            throw new CommonException(StatusCode.USER_NOT_FOUND.getCode(),
                    StatusCode.USER_NOT_FOUND.getMsg());
        }

        // 1-纯充值   2-添加会员时顺便充值 3-修改会员时充值
        if (carRecharge.getRechargeFlag().intValue() == CarRechargeFlagEnum.NORMAL_RECHARGE.VALUE
                || carRecharge.getRechargeFlag().intValue() == CarRechargeFlagEnum.ADD_USER_RECHARGE.VALUE
                || carRecharge.getRechargeFlag().intValue() == CarRechargeFlagEnum.UPDATE_USER_RECHARGE.VALUE) {
            if (Utils.isEmpty(carRecharge.getAmount()) || carRecharge.getAmount() <= 0) {
                throw new CommonException("", "充值金额必填，且必须大于0.00元");
            }

            // 1.获取config_recharge表，符合充值金额最大的一个
            // 循环/不循环赠送积分、返现、赠送金额等；其中按固定金额充值，一定不循环赠送
            // 固定值充值 or 自由充值 1-固定金额充值  2-非固定金额充值（如果不填，默认非固定金额充值）
            if (Utils.isEmpty(carRecharge.getRechargeType())) {
                carRecharge.setRechargeType(ConfigRechargeTypeEnum.CYCLE__RECHARGE_AMOUNT.VALUE);
            }

            // 下面的查询相当于如下sql：
            // select * from config_recharge
            // where recharge_amount <= 50000 and del_flag=0 and type=2
            //  order by recharge_amount desc
            //  limit 1
            QueryWrapper<ConfigRecharge> configRechargeQueryWrapper = new QueryWrapper<>();
            configRechargeQueryWrapper.eq(ConfigRecharge.TYPE, carRecharge.getRechargeType());
            configRechargeQueryWrapper.le(ConfigRecharge.RECHARGE_AMOUNT, carRecharge.getAmount());
            configRechargeQueryWrapper.orderByDesc(ConfigRecharge.RECHARGE_AMOUNT);
            configRechargeQueryWrapper.last("limit 1");

            int rechargeAmount = carRecharge.getAmount(); // 待充值金额
            int rechargeSendAmount = 0; // 充值赠送金额
            int sendCash = 0; // 返现
            int sendIntegral = 0; // 赠送积分
            ConfigRecharge configRecharge = configRechargeService.getOne(configRechargeQueryWrapper);
            if (Utils.notEmpty(configRecharge)) {
                if (configRecharge.getType().intValue() == ConfigRechargeTypeEnum.CYCLE__RECHARGE_AMOUNT.VALUE) {

                    // 非固定值充值 查看是否循环赠送，
                    if (configRecharge.getOverflyFlag().intValue() == ConfigRechargeOverflyFlagEnum.NOT_RECHARGE_SEND_AMOUNT.VALUE) {
                        // 不循环
                        rechargeSendAmount = configRecharge.getRechargeSendAmount();
                        sendCash = configRecharge.getSendCash();
                        sendIntegral = configRecharge.getSendIntegral();
                    } else {
                        if (Utils.isEmpty(configRecharge.getRechargeAmount()) || configRecharge.getRechargeAmount() <= 0) {
                            throw new CommonException("", "请检查充值设置，无固定金额充值时，采用循环赠送时，最低充值金额不能为空，且必须大于0.00元！");
                        }
                        // 循环
                        // 获得循环次数
                        int cycleSendCnt = carRecharge.getAmount() / configRecharge.getRechargeAmount();
                        rechargeSendAmount = configRecharge.getRechargeSendAmount() * cycleSendCnt;
                        sendCash = configRecharge.getSendCash() * cycleSendCnt;
                        sendIntegral = configRecharge.getSendIntegral() * cycleSendCnt;
                    }
                } else {

                    // 固定值充值
                    rechargeSendAmount = configRecharge.getRechargeSendAmount();
                    sendCash = configRecharge.getSendCash();
                    sendIntegral = configRecharge.getSendIntegral();
                }
            }

            if (carRecharge.getPayWay().intValue() == CarPayWayEnum.WX_PAY.VALUE) {
                throw new CommonException("", "管理端充值不可以选择微信线上充值方式！");
            }


            // 2.插入充值记录
            CarRecharge newCarRecharge = new CarRecharge();
            newCarRecharge.setDelFlag(carRecharge.getDelFlag());
            newCarRecharge.setCreateTime(carRecharge.getCreateTime());
            newCarRecharge.setUpdateTime(carRecharge.getUpdateTime());
            newCarRecharge.setCreateUser(carRecharge.getCreateUser());
            newCarRecharge.setUpdateUser(carRecharge.getUpdateUser());
            newCarRecharge.setRechargeNo(BusinessUtils.generatorRechargeNo());// 充值流水号（我们系统）
            newCarRecharge.setUserId(carRecharge.getUserId());
            newCarRecharge.setPayWay(carRecharge.getPayWay());
            newCarRecharge.setStatus(30); // 10-未支付  20-已审核  30-支付成功  40-支付失败
            newCarRecharge.setPayTime(new Date());
            newCarRecharge.setAmount(rechargeAmount);
            ret = ret && this.save(newCarRecharge);

            if (!ret) {
                throw new CommonException("", "充值失败，请检查参数");
            }

            // 3.插入wallet_log 日志
            // 4.修改wallet
            QueryWrapper<CarUserWallet> carUserWalletQueryWrapper = new QueryWrapper<>();
            carUserWalletQueryWrapper.eq(CarUserWallet.CARD_CATEGORY, carRecharge.getCardCategory());
            carUserWalletQueryWrapper.eq(CarUserWallet.USER_ID, carRecharge.getUserId());
            CarUserWallet oWallet = carUserWalletService.getOne(carUserWalletQueryWrapper);
            if (Utils.notEmpty(oWallet)) {
                // 能找到钱包，则修改钱包
                CarUserWalletLog beforeLog = new CarUserWalletLog();
                beforeLog.setUserId(carRecharge.getUserId());
                beforeLog.setTotalWallet(oWallet.getTotalWallet());
                beforeLog.setIntegral(oWallet.getIntegral());
                beforeLog.setSendCash(oWallet.getSendCash());
                beforeLog.setSendAmount(oWallet.getSendAmount());
                beforeLog.setBusType(CarWalletLogBusTypeEnum.RECHARGE.VALUE);
                beforeLog.setPayway(carRecharge.getPayWay());
                beforeLog.setType(1);
                beforeLog.setChangeAmount(rechargeAmount);
                beforeLog.setWallet(oWallet.getWallet());
                beforeLog.setRemark("管理端人工充值");
                beforeLog.setCreateTime(carRecharge.getUpdateTime());
                ret = ret && carUserWalletLogService.save(beforeLog);

                CarUserWalletLog afterLog = new CarUserWalletLog();
                afterLog.setUserId(carRecharge.getUserId());
                afterLog.setTotalWallet(oWallet.getTotalWallet() + rechargeAmount + rechargeSendAmount + sendCash);
                afterLog.setIntegral(oWallet.getIntegral() + sendIntegral);
                afterLog.setSendCash(oWallet.getSendCash() + sendCash);
                afterLog.setSendAmount(oWallet.getSendAmount() + rechargeSendAmount);
                afterLog.setBusType(CarWalletLogBusTypeEnum.RECHARGE.VALUE);
                afterLog.setPayway(carRecharge.getPayWay());
                afterLog.setType(2);
                afterLog.setChangeAmount(rechargeAmount);
                afterLog.setWallet(oWallet.getWallet() + rechargeAmount);
                afterLog.setRemark("管理端人工充值");
                afterLog.setCreateTime(carRecharge.getUpdateTime());
                ret = ret && carUserWalletLogService.save(afterLog);

                oWallet.setTotalWallet(afterLog.getTotalWallet());
                oWallet.setWallet(afterLog.getWallet());
                oWallet.setSendAmount(afterLog.getSendAmount());
                oWallet.setSendCash(afterLog.getSendCash());
                oWallet.setIntegral(afterLog.getIntegral());
                if (Utils.notEmpty(carRecharge.getStartTime())) {
                    oWallet.setStartTime(carRecharge.getStartTime());
                }
                if (Utils.notEmpty(carRecharge.getEndTime())) {
                    oWallet.setEndTime(carRecharge.getEndTime());
                }
                ret = ret && carUserWalletService.updateById(oWallet);

            } else {
                // 找不到钱包，则新增钱包
                CarUserWalletLog beforeLog = new CarUserWalletLog();
                beforeLog.setUserId(carRecharge.getUserId());
                beforeLog.setTotalWallet(0);
                beforeLog.setIntegral(0);
                beforeLog.setSendCash(0);
                beforeLog.setSendAmount(0);
                beforeLog.setBusType(CarWalletLogBusTypeEnum.RECHARGE.VALUE);
                beforeLog.setPayway(carRecharge.getPayWay());
                beforeLog.setType(1);
                beforeLog.setChangeAmount(rechargeAmount);
                beforeLog.setWallet(0);
                beforeLog.setRemark("管理端人工充值");
                beforeLog.setCreateTime(carRecharge.getUpdateTime());
                ret = ret && carUserWalletLogService.save(beforeLog);

                CarUserWalletLog afterLog = new CarUserWalletLog();
                afterLog.setUserId(carRecharge.getUserId());
                afterLog.setTotalWallet(rechargeAmount + rechargeSendAmount + sendCash);
                afterLog.setIntegral(sendIntegral);
                afterLog.setSendCash(sendCash);
                afterLog.setSendAmount(rechargeSendAmount);
                afterLog.setBusType(CarWalletLogBusTypeEnum.RECHARGE.VALUE);
                afterLog.setPayway(carRecharge.getPayWay());
                afterLog.setType(2);
                afterLog.setChangeAmount(rechargeAmount);
                afterLog.setWallet(rechargeAmount);
                afterLog.setRemark("管理端人工充值");
                afterLog.setCreateTime(carRecharge.getUpdateTime());
                ret = ret && carUserWalletLogService.save(afterLog);

                CarUserWallet nWallet = new CarUserWallet();
                nWallet.setTotalWallet(afterLog.getTotalWallet());
                nWallet.setWallet(afterLog.getWallet());
                nWallet.setSendAmount(afterLog.getSendAmount());
                nWallet.setSendCash(afterLog.getSendCash());
                nWallet.setIntegral(afterLog.getIntegral());
                nWallet.setCardCategory(carRecharge.getCardCategory());
                nWallet.setRefundTotalWallet(0);
                nWallet.setRefundIntegral(0);
                nWallet.setRefundCash(0);
                nWallet.setRefundAmount(0);
                nWallet.setStatus(1);
                nWallet.setRefundWallet(0);
                nWallet.setDelFlag(DeleteFlagEnum.FALSE.VALUE);
                if (Utils.notEmpty(carRecharge.getStartTime())) {
                    nWallet.setStartTime(carRecharge.getStartTime());
                }
                if (Utils.notEmpty(carRecharge.getEndTime())) {
                    nWallet.setEndTime(carRecharge.getEndTime());
                }
                nWallet.setCreateTime(carRecharge.getUpdateTime());
                nWallet.setUpdateTime(carRecharge.getUpdateTime());
                nWallet.setCreateUser(carRecharge.getUpdateUser());
                nWallet.setUpdateUser(carRecharge.getUpdateUser());
                ret = ret && carUserWalletService.save(nWallet);
            }

            if (!ret) {
                throw new CommonException("", "充值失败！请联系管理员");
            }

            responseMessageVO.setRetType("管理端充值");
            responseMessageVO.setRetFlag(ret);
            responseMessageVO.setRetMsg("管理端充值，充值用户ID：" + carRecharge.getUserId()
                    + ";充值记录单号：" + newCarRecharge.getRechargeNo() + ";充值记录ID:" + newCarRecharge.getId());
        }

        // rechargeFlag = 4;4-修改会员时修改余额
        // 不用获取configRecharge,只需要修改wallet金额，wallet_log插入两组数据，分别是手动减少和手动增加的
        if (carRecharge.getRechargeFlag().intValue() == CarRechargeFlagEnum.UPDATE_USER_WALLET.VALUE) {

            if (Utils.isEmpty(carRecharge.getAmount()) || carRecharge.getAmount() <= 0) {
                throw new CommonException("", "待修改金额必填，且必须大于0.00元");
            }

            int rechargeAmount = carRecharge.getAmount(); // 待修改金额(相当于wallet表的wallet字段）
            int rechargeSendAmount = carRecharge.getSendAmount(); // 待修改赠送金额
            int sendCash = carRecharge.getSendCash(); // 待修改返现金额
            int sendIntegral = carRecharge.getIntegral(); // 待修改赠送积分

            // 单纯修改用户余额，不必记录余额充值方式
            // 3.插入wallet_log 日志
            // 4.修改wallet
            QueryWrapper<CarUserWallet> carUserWalletQueryWrapper = new QueryWrapper<>();
            carUserWalletQueryWrapper.eq(CarUserWallet.CARD_CATEGORY, carRecharge.getCardCategory());
            carUserWalletQueryWrapper.eq(CarUserWallet.USER_ID, carRecharge.getUserId());
            CarUserWallet oWallet = carUserWalletService.getOne(carUserWalletQueryWrapper);
            if (Utils.isEmpty(oWallet)) {
                throw new CommonException("", "会员卡信息不存在！");
            }

            // 变更前日志
            CarUserWalletLog beforeChangeBeforeWalletLog = new CarUserWalletLog();
            beforeChangeBeforeWalletLog.setCreateTime(new Date());
            beforeChangeBeforeWalletLog.setUserId(carRecharge.getUserId());
            beforeChangeBeforeWalletLog.setTotalWallet(oWallet.getTotalWallet());
            beforeChangeBeforeWalletLog.setIntegral(oWallet.getIntegral());
            beforeChangeBeforeWalletLog.setSendCash(oWallet.getSendCash());
            beforeChangeBeforeWalletLog.setSendAmount(oWallet.getSendAmount());
            beforeChangeBeforeWalletLog.setBusType(CarWalletLogBusTypeEnum.MANUAL_MINUS.VALUE);
            beforeChangeBeforeWalletLog.setType(1);
            beforeChangeBeforeWalletLog.setChangeAmount(rechargeAmount);
            beforeChangeBeforeWalletLog.setWallet(oWallet.getWallet());
            beforeChangeBeforeWalletLog.setRemark("管理端手动修改");
            ret = ret && carUserWalletLogService.save(beforeChangeBeforeWalletLog);

            CarUserWalletLog beforeChangeAfterWalletLog = new CarUserWalletLog();
            beforeChangeAfterWalletLog.setCreateTime(new Date());
            beforeChangeAfterWalletLog.setUserId(carRecharge.getUserId());
            beforeChangeAfterWalletLog.setTotalWallet(0);
            beforeChangeAfterWalletLog.setIntegral(0);
            beforeChangeAfterWalletLog.setSendCash(0);
            beforeChangeAfterWalletLog.setSendAmount(0);
            beforeChangeAfterWalletLog.setBusType(CarWalletLogBusTypeEnum.MANUAL_MINUS.VALUE);
            beforeChangeAfterWalletLog.setType(2);
            beforeChangeAfterWalletLog.setChangeAmount(rechargeAmount);
            beforeChangeAfterWalletLog.setWallet(0);
            beforeChangeAfterWalletLog.setRemark("管理端手动修改");
            ret = ret && carUserWalletLogService.save(beforeChangeBeforeWalletLog);


            // 能找到钱包，则修改钱包
            oWallet.setUpdateTime(new Date());
            oWallet.setUpdateUser(carRecharge.getUpdateUser());
            oWallet.setTotalWallet(rechargeAmount + sendCash + rechargeSendAmount);
            oWallet.setWallet(rechargeAmount);
            oWallet.setIntegral(sendIntegral);
            oWallet.setSendCash(sendCash);
            oWallet.setSendAmount(rechargeSendAmount);
            if(Utils.notEmpty(carRecharge.getStartTime())){
                oWallet.setStartTime(carRecharge.getStartTime());
            }
            if(Utils.notEmpty(carRecharge.getEndTime())){
                oWallet.setEndTime(carRecharge.getEndTime());
            }
            ret = ret && carUserWalletService.updateById(oWallet);


            CarUserWalletLog afterChangeBeforeWalletLog = new CarUserWalletLog();
            afterChangeBeforeWalletLog.setUserId(carRecharge.getUserId());
            afterChangeBeforeWalletLog.setTotalWallet(0);
            afterChangeBeforeWalletLog.setIntegral(0);
            afterChangeBeforeWalletLog.setSendCash(0);
            afterChangeBeforeWalletLog.setSendAmount(0);
            afterChangeBeforeWalletLog.setBusType(CarWalletLogBusTypeEnum.MANUAL_ADD.VALUE);
            afterChangeBeforeWalletLog.setType(1);
            afterChangeBeforeWalletLog.setChangeAmount(0);
            afterChangeBeforeWalletLog.setWallet(0);
            afterChangeBeforeWalletLog.setRemark("管理端人工修改");
            afterChangeBeforeWalletLog.setCreateTime(carRecharge.getUpdateTime());
            ret = ret && carUserWalletLogService.save(afterChangeBeforeWalletLog);

            CarUserWalletLog afterChangeAfterWalletLog = new CarUserWalletLog();
            afterChangeAfterWalletLog.setUserId(carRecharge.getUserId());
            afterChangeAfterWalletLog.setTotalWallet(rechargeAmount + rechargeSendAmount + sendCash);
            afterChangeAfterWalletLog.setIntegral(sendIntegral);
            afterChangeAfterWalletLog.setSendCash(sendCash);
            afterChangeAfterWalletLog.setSendAmount(rechargeSendAmount);
            afterChangeAfterWalletLog.setBusType(CarWalletLogBusTypeEnum.MANUAL_ADD.VALUE);
            afterChangeAfterWalletLog.setType(2);
            afterChangeAfterWalletLog.setChangeAmount(rechargeAmount);
            afterChangeAfterWalletLog.setWallet(rechargeAmount);
            afterChangeAfterWalletLog.setRemark("管理端人工修改");
            afterChangeAfterWalletLog.setCreateTime(carRecharge.getUpdateTime());
            ret = ret && carUserWalletLogService.save(afterChangeAfterWalletLog);


            responseMessageVO.setRetType("管理端用户余额修改");
            responseMessageVO.setRetFlag(ret);
            responseMessageVO.setRetMsg("管理端用户余额修改，用户ID：" + carRecharge.getUserId() + ";修改余额由："
                    + beforeChangeBeforeWalletLog.getChangeAmount() / 100 + "元,变成：" + rechargeAmount /100 +"元");
        }

        return responseMessageVO;
    }
}
